<template>
  <div id="common_table">
    <div class="table_title">
      <slot name="tableSearchForm"></slot>
      <div>
        <a-tooltip>
          <template #title> 刷新 </template>
          <ReloadOutlined @click="getPage()" />
        </a-tooltip>
        <a-dropdown :trigger="['click']" placement="bottom">
          <a-tooltip>
            <template #title> 密度 </template>
            <ColumnHeightOutlined />
          </a-tooltip>
          <template #overlay>
            <a-menu v-model:selectedKeys="tableSzie" @click="changeSizeKey">
              <a-menu-item v-for="item in sizeMenu" :key="item.key"> {{ item.label }}</a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
        <a-popover trigger="click" placement="bottomLeft">
          <template #title>
            <a-row class="">
              <a-col :span="12">
                <a-checkbox v-model:checked="tableBordered">带边框</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox v-model:checked="tableStriped">斑马线</a-checkbox>
              </a-col>
            </a-row>
          </template>
          <a-tooltip>
            <template #title> 设置 </template>
            <SettingOutlined />
          </a-tooltip>
          <template #content>
            <a-row style="width: 400px">
              <a-col :span="10"><TableOutlined /> 展示的列 </a-col>
              <a-col :span="7">对齐方式</a-col>
              <a-col :span="7" style="text-align: center">根据此项排序</a-col>
              <template v-for="item in columns" :key="item.key">
                <a-col :span="10">
                  <HolderOutlined class="handle cursor-move" />
                  <a-checkbox
                    v-model:checked="item.showCol"
                    :disabled="item.disableHidden || !!item.fixed"
                  >
                    {{ item.title }}
                  </a-checkbox>
                </a-col>
                <a-col :span="7">
                  <a-select
                    v-model:value="item.align"
                    :disabled="item.disableHidden || !!item.fixed"
                    style="width: 100%"
                  >
                    <a-select-option v-for="sItem in alignMenu" :key="`${sItem}`" :value="sItem">
                      {{ sItem }}
                    </a-select-option>
                  </a-select>
                </a-col>
                <a-col :span="7" style="text-align: center">
                  <a-switch v-model:checked="item.sorter" :disabled="item.key === 'action'"
                /></a-col>
              </template>
            </a-row>
          </template>
        </a-popover>
      </div>
    </div>
    <div class="table_content">
      <a-table
        :dataSource="dataSource"
        :rowKey="props.rowKey"
        :columns="columns.filter((c) => c.showCol)"
        :loading="loading"
        :scroll="{ x: tableScrollW }"
        :pagination="false"
        @change="tableChange"
        :size="tableSzie[0]"
        :bordered="tableBordered"
        :class="tableStriped ? 'ant-table-striped' : ''"
        :row-selection="props.tableSelected ? rowSelection : undefined"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column?.key && column.key === 'action'">
            <slot name="otherAction" :record="record" :column="column"> </slot>
          </template>
        </template>
      </a-table>
    </div>
    <div class="table_footer">
      <div></div>
      <a-pagination
        class="common_pagination"
        v-model:current="page"
        v-model:page-size="limit"
        :total="total"
        show-size-changer
        show-quick-jumper
        :show-total="(total: number) => `共 ${total} 条`"
        :page-size-options="['10', '15', '20', '30', '40', '50']"
        @change="changePagination"
        @showSizeChange="changePagination"
      >
        <template #buildOptionText="props">
          <span v-if="props.value !== '50'">{{ props.value }}条/页</span>
          <span v-if="props.value === '50'">全部</span>
        </template>
      </a-pagination>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, watchEffect, watch, onBeforeUnmount } from 'vue'
import { tableProps } from './props'
import storageUtil from '@/utils/storage_util'
import { validatorHttp, consulateHttp } from '@/axios/index'
import { find } from 'lodash-es'

import {
  ReloadOutlined,
  ColumnHeightOutlined,
  HolderOutlined,
  TableOutlined,
  SettingOutlined
} from '@ant-design/icons-vue'
import type { SizeType, TColumn } from './type.ts'
import type { TableProps } from 'ant-design-vue'
const emit = defineEmits(['searchFinish', 'getCustomCol'])
const tableSzie = ref<['large' | 'middle' | 'small']>(['middle'])
const alignMenu = ['left', 'right', 'center']
const sizeMenu = ref<SizeType[]>([
  {
    key: 'large',
    label: '宽松'
  },
  {
    key: 'middle',
    label: '默认'
  },
  {
    key: 'small',
    label: '紧凑'
  }
])
const tableBordered = ref(false)
const tableStriped = ref(false)
const loading = ref<boolean>(false)
const props = defineProps(tableProps)
const dataSource = ref<any[]>([])
const columns = ref<any[]>(props.columns)
const storeTable = storageUtil.get(`table_setting_${props.name}`)
if (storeTable) {
  tableBordered.value = storeTable.border
  tableStriped.value = storeTable.striped
  tableSzie.value = storeTable.size
  const list = storeTable.columns || []
  const copyList: any[] = []
  columns.value.forEach((item) => {
    const info = find(list, function (f) {
      return f.key === item.key || f.dataIndex === item.dataIndex
    })
    if (info) {
      Object.keys(info).forEach((iitem) => {
        item[iitem as keyof TColumn] = info[iitem]
      })
    }
    copyList.push(item)
  })
  columns.value = copyList
}

console.log(
  '%c [ columns.value ]-170',
  'font-size:13px; background:pink; color:#bf2c9f;',
  columns.value
)
const tableScrollW = ref<number>(0)

const stopWatcher = watch(
  columns,
  () => {
    tableScrollW.value = 0
    columns.value.forEach((col) => {
      if (col.showCol) {
        tableScrollW.value += col.width as number
      }
    })
  },
  { deep: true }
)
const total = ref(0)
const page = ref(1)
const limit = ref(10)
const orderBys = ref([
  {
    orderField: '',
    asc: true
  }
])
if (props.queryStore) {
  const storeParams = storageUtil.get(props.queryStore)
  if (storeParams) {
    page.value = storeParams.page || 1
    limit.value = storeParams.limit || 10
    orderBys.value = storeParams.orderBys
  }
}
const rowSelection: TableProps['rowSelection'] = {
  onChange: (selectedRowKeys: any[], selectedRows: any[]) => {
    console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
  },
  getCheckboxProps: (record: any) => ({
    name: record.name
  })
}
function tableChange(pagination: any, filters: any, sorter: any) {
  if (sorter.order) {
    orderBys.value = [
      {
        asc: sorter.order === 'ascend',
        orderField: sorter.columnKey
      }
    ]
  } else {
    orderBys.value = [
      {
        asc: true,
        orderField: ''
      }
    ]
  }
  getPage()
}
function changeSizeKey(e: any) {
  const { key } = e as {
    key: 'large' | 'middle' | 'small'
  }
  tableSzie.value = [key]
}
function changePagination(current: number, size: number) {
  limit.value = size
  page.value = current
  getPage()
}
function getPage(param?: any) {
  const axiosParams = ref({
    page: page.value,
    limit: limit.value,
    param: {
      ...props.queryParams,
      ...param
    },
    orderBys: orderBys.value
  })
  if (props.queryServe === 'validator') {
    validatorHttp
      .request({
        method: 'POST',
        data: axiosParams.value,
        url: props.queryApi
      })
      .then((res) => {
        dataSource.value = res.data || []
        loading.value = false
        total.value = res.count || 0
        emit('searchFinish', axiosParams.value, true)
        if (props.customCol) {
          emit('getCustomCol', {
            val: dataSource.value,
            callback: (result: any) => {
              console.log(
                '%c [ result ]-274',
                'font-size:13px; background:pink; color:#bf2c9f;',
                result
              )
              dataSource.value = result
            }
          })
        }
      })
      .catch(() => {
        loading.value = false
        emit('searchFinish', axiosParams.value, false)
      })
  } else {
    consulateHttp
      .request({
        method: 'POST',
        data: axiosParams.value,
        url: props.queryApi
      })
      .then((res) => {
        dataSource.value = res.data || []
        loading.value = false
        total.value = res.count || 0
        emit('searchFinish', axiosParams.value, true)
      })
      .catch(() => {
        loading.value = false
        emit('searchFinish', axiosParams.value, false)
      })
  }
}
defineExpose({
  getPage
})
watchEffect(() => {
  const storeInfo = {
    size: tableSzie.value,
    border: tableBordered.value,
    striped: tableStriped.value,
    columns: columns.value
  }
  storageUtil.set(`table_setting_${props.name}`, storeInfo)
})
onBeforeUnmount(() => {
  stopWatcher()
})
</script>
<style lang="scss" scoped>
#common_table {
  @include w-h-cover();
  @include flex-column();
}
.table_title {
  padding: 5px 10px;
  @include flex-between();
  background: #e5e5e5;
}
.table_footer {
  padding: 5px 10px;
  @include flex-between();
  background: #e5e5e5;
}
</style>
<style lang="scss">
#common_table {
  .ant-table-striped {
    .ant-table-tbody {
      tr:nth-child(2n) td {
        background: #fff;
      }
      tr:nth-child(2n + 1) td {
        background: #f1f1f1;
      }
    }
  }
}
</style>
